#ifndef __DATA_UNIT_H__
#define __DATA_UNIT_H__

#include <iostream>
#include <vector>
#include <exception>

using namespace std;

namespace dataunits {

class EndOfDataException : public exception{
public:
	EndOfDataException(){};
	virtual ~EndOfDataException() throw(){};
};

class DataUnit {
public:
	DataUnit() {}
	virtual int asInt() const =0;
	virtual void writeOn(ostream& os) =0;
	virtual bool operator==(const DataUnit& other) =0;
	virtual bool operator<(const DataUnit& other) =0;
	virtual ~DataUnit() {}
};


class Escape : public DataUnit {
public:
	Escape() {}
	int asInt() const { return 257; }
	void writeOn(ostream& os) {}
	bool operator==(const DataUnit& other) { return (other.asInt() == 257); }
	bool operator<(const DataUnit& other) { return false; }
	virtual ~Escape() {}
};

class EndOfFileDataUnit : public DataUnit {
public:
	EndOfFileDataUnit() {}
	int asInt() const { return 258; }
	void writeOn(ostream& os) {}
	bool operator==(const DataUnit& other) { return (other.asInt() == 258); }
	bool operator<(const DataUnit& other) { return false; }
	virtual ~EndOfFileDataUnit() {}
};


class DataUnitFactory {
public:
	DataUnitFactory() {}
	virtual vector<DataUnit*>& getAll() =0;
	virtual DataUnit* createDataUnitFor(unsigned int value) =0;
	virtual ~DataUnitFactory() {}
};


}


#endif // __DATA_UNIT_H__
